Olaf Klein contributes a new filter for merging and splitting tracks.
authorrobertl <robertl@f51c46e8-681c-474f-0cfe-069cfd0219fb>
Wed, 22 Jun 2005 18:10:54 +0000 (18:10 +0000)
committerrobertl <robertl@f51c46e8-681c-474f-0cfe-069cfd0219fb>
Wed, 22 Jun 2005 18:10:54 +0000 (18:10 +0000)
gpsbabel/Makefile
gpsbabel/README
gpsbabel/filter_vecs.c
gpsbabel/reference/track/trackfilter-new.gpx [new file with mode: 0644]
gpsbabel/reference/track/trackfilter.gpx [new file with mode: 0644]
gpsbabel/testo
gpsbabel/trackfilter.c [new file with mode: 0644]

index f2a2847cd16a209f3f5073f2649c483926cd4cdb..1aee0130a98e92e2d89ab1d8177adfaf3535c101 100644 (file)
@@ -30,7 +30,7 @@ FMTS=magproto.o gpx.o geo.o mapsend.o mapsource.o garmin_tables.o \
        vcf.o overlay.o kml.o google.o lowranceusr.o an1.o tomtom.o \
        tef_xml.o maggeo.o pathaway.o vitosmt.o
 
-FILTERS=position.o duplicate.o arcdist.o polygon.o smplrout.o reverse_route.o sort.o stackfilter.o
+FILTERS=position.o duplicate.o arcdist.o polygon.o smplrout.o reverse_route.o sort.o stackfilter.o trackfilter.o
 
 OSJEEPS=jeeps/gpslibusb.o
 JEEPS=jeeps/gpsapp.o jeeps/gpscom.o \
@@ -223,6 +223,7 @@ tpg.o: tpg.c defs.h queue.h gbtypes.h jeeps/gpsmath.h jeeps/gps.h \
   jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h \
   jeeps/gpsfmt.h jeeps/gpsnmea.h jeeps/gpsmem.h jeeps/gpsrqst.h \
   jeeps/gpsinput.h jeeps/gpsproj.h jeeps/gpsnmeafmt.h jeeps/gpsnmeaget.h
+trackfilter.o: trackfilter.c defs.h queue.h gbtypes.h
 util.o: util.c defs.h queue.h gbtypes.h
 util_crc.o: util_crc.c
 uuid.o: uuid.c uuid.h
index 5b4e45f34fc18803c16e44a77908342546ff3547..d3c0101f154f4311b54062cc18955445b6a863ec 100644 (file)
@@ -1127,3 +1127,54 @@ DATA FILTERS
                     -x stack,pop,append \
                     -o magellan -F fwaind.wpt
  
+
+    TRACK
+
+        The track filter is a tool for manipulating track lists.  The
+        following options are available:
+
+        TITLE
+
+            Gives the new track(s) a basic title. Basic means if more
+            than one track is created by filter the title will be
+            expanded with the date the new track. Special formats (see
+            UNIX date or strftime for details) are possible.
+
+            gpsbabel -t \
+               -i gpx -f in.gpx  \
+                 -x track,pack,split,title="ACTIVE LOG-%D" \ 
+               -o gpx -F out.gpx PACK
+
+            With this default option all tracks from input will be
+            packed into one track. If tracks overlaps in time, the
+            filter stops working.   To pack all the tracks together
+           into one track and give it a name, use this:
+
+           gpsbabel -t \
+                    -i gpx -f in.gpx \
+                    -x track,pack,title="ACTIVE LOG" \
+                    -o gpx -F out.gpx
+                    
+       SPLIT
+       
+           The input track will be split into several tracks 
+           depending on date of track points. If there is more 
+           than one track, use the pack option before before 
+           using this. 
+  
+           To split a single tracks into separate tracks for each day
+           and name them, use this:
+           gpsbabel -t \
+                    -i gpx -f in.gpx \
+                    -x track,split,title="ACTIVE LOG # %Y%m%d" \
+                    -o gpx -F out.gpx
+
+           If the input has multiple tracks, pack them together before
+           splitting them back apart per day thusly:
+           
+           gpsbabel -t \
+                    -i gpx -f in.gpx \
+                    -x track,pack,split,title="ACTIVE LOG # %D" \
+                    -o gpx -F out.gpx
+
index 08b832f83d491cd5c6856b8d366b2a571c741c51..646f486e51ebf5ba9fad1487e1c51690a53f8fd3 100644 (file)
@@ -37,6 +37,7 @@ extern filter_vecs_t routesimple_vecs;
 extern filter_vecs_t reverse_route_vecs;
 extern filter_vecs_t sort_vecs;
 extern filter_vecs_t stackfilt_vecs;
+extern filter_vecs_t trackfilter_vecs;
 
 static
 fl_vecs_t filter_vec_list[] = {
@@ -85,6 +86,11 @@ fl_vecs_t filter_vec_list[] = {
                "stack",
                "Save and restore waypoint lists"
        },
+       {
+               &trackfilter_vecs,
+               "track",
+               "Manipulate track lists"
+       },
         {
                NULL,
                NULL,
diff --git a/gpsbabel/reference/track/trackfilter-new.gpx b/gpsbabel/reference/track/trackfilter-new.gpx
new file mode 100644 (file)
index 0000000..c654916
--- /dev/null
@@ -0,0 +1,280 @@
+<?xml version="1.0"?>
+<gpx
+ version="1.0"
+creator="GPSBabel - http://www.gpsbabel.org"
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xmlns="http://www.topografix.com/GPX/1/0"
+xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/GPX/1/0/gpx.xsd">
+<time>2005-06-15T22:44:09Z</time>
+<trk>
+  <name>LOG-20020525</name>
+<trkseg>
+<trkpt lat="30.062183" lon="-91.610350">
+  <ele>1.000000</ele>
+<time>2002-05-25T17:06:21Z</time>
+</trkpt>
+<trkpt lat="30.062783" lon="-91.610567">
+  <ele>0.000000</ele>
+<time>2002-05-25T17:09:55Z</time>
+</trkpt>
+<trkpt lat="30.062700" lon="-91.608267">
+  <ele>0.000000</ele>
+<time>2002-05-25T17:12:00Z</time>
+</trkpt>
+<trkpt lat="30.062333" lon="-91.607383">
+  <ele>0.000000</ele>
+<time>2002-05-25T17:12:48Z</time>
+</trkpt>
+<trkpt lat="30.061533" lon="-91.605283">
+  <ele>0.000000</ele>
+<time>2002-05-25T17:14:41Z</time>
+</trkpt>
+<trkpt lat="30.059783" lon="-91.599400">
+  <ele>0.000000</ele>
+<time>2002-05-25T17:17:16Z</time>
+</trkpt>
+<trkpt lat="30.057800" lon="-91.596683">
+  <ele>0.000000</ele>
+<time>2002-05-25T17:17:46Z</time>
+</trkpt>
+<trkpt lat="30.055383" lon="-91.594900">
+  <ele>0.000000</ele>
+<time>2002-05-25T17:18:20Z</time>
+</trkpt>
+<trkpt lat="30.053883" lon="-91.592617">
+  <ele>0.000000</ele>
+<time>2002-05-25T17:19:01Z</time>
+</trkpt>
+<trkpt lat="30.049733" lon="-91.589750">
+  <ele>0.000000</ele>
+<time>2002-05-25T17:20:46Z</time>
+</trkpt>
+<trkpt lat="30.049017" lon="-91.589883">
+  <ele>0.000000</ele>
+<time>2002-05-25T17:21:10Z</time>
+</trkpt>
+<trkpt lat="30.048800" lon="-91.592933">
+  <ele>0.000000</ele>
+<time>2002-05-25T17:21:51Z</time>
+</trkpt>
+<trkpt lat="30.046233" lon="-91.596450">
+  <ele>0.000000</ele>
+<time>2002-05-25T17:22:35Z</time>
+</trkpt>
+<trkpt lat="30.045517" lon="-91.598717">
+  <ele>0.000000</ele>
+<time>2002-05-25T17:23:08Z</time>
+</trkpt>
+<trkpt lat="30.047300" lon="-91.600267">
+  <ele>0.000000</ele>
+<time>2002-05-25T18:04:23Z</time>
+</trkpt>
+<trkpt lat="30.047000" lon="-91.599633">
+  <ele>2.000000</ele>
+<time>2002-05-25T18:06:04Z</time>
+</trkpt>
+<trkpt lat="30.046433" lon="-91.599467">
+  <ele>0.000000</ele>
+<time>2002-05-25T18:07:06Z</time>
+</trkpt>
+<trkpt lat="30.046200" lon="-91.598950">
+  <ele>1.000000</ele>
+<time>2002-05-25T18:08:18Z</time>
+</trkpt>
+<trkpt lat="30.046367" lon="-91.597733">
+  <ele>0.000000</ele>
+<time>2002-05-25T18:10:20Z</time>
+</trkpt>
+<trkpt lat="30.046350" lon="-91.597167">
+  <ele>0.000000</ele>
+<time>2002-05-25T18:11:09Z</time>
+</trkpt>
+<trkpt lat="30.046783" lon="-91.596333">
+  <ele>0.000000</ele>
+<time>2002-05-25T18:12:18Z</time>
+</trkpt>
+<trkpt lat="30.047450" lon="-91.595200">
+  <ele>0.000000</ele>
+<time>2002-05-25T18:14:22Z</time>
+</trkpt>
+<trkpt lat="30.047800" lon="-91.594767">
+  <ele>2.000000</ele>
+<time>2002-05-25T18:15:04Z</time>
+</trkpt>
+<trkpt lat="30.048250" lon="-91.594083">
+  <ele>1.000000</ele>
+<time>2002-05-25T18:16:14Z</time>
+</trkpt>
+<trkpt lat="30.048683" lon="-91.593800">
+  <ele>1.000000</ele>
+<time>2002-05-25T18:17:01Z</time>
+</trkpt>
+<trkpt lat="30.049350" lon="-91.593850">
+  <ele>0.000000</ele>
+<time>2002-05-25T18:18:07Z</time>
+</trkpt>
+<trkpt lat="30.050317" lon="-91.593983">
+  <ele>2.000000</ele>
+<time>2002-05-25T18:19:51Z</time>
+</trkpt>
+<trkpt lat="30.050783" lon="-91.594117">
+  <ele>0.000000</ele>
+<time>2002-05-25T18:20:39Z</time>
+</trkpt>
+<trkpt lat="30.051233" lon="-91.594367">
+  <ele>0.000000</ele>
+<time>2002-05-25T18:21:24Z</time>
+</trkpt>
+<trkpt lat="30.051800" lon="-91.594367">
+  <ele>0.000000</ele>
+<time>2002-05-25T18:22:17Z</time>
+</trkpt>
+<trkpt lat="30.052217" lon="-91.594667">
+  <ele>0.000000</ele>
+<time>2002-05-25T18:23:18Z</time>
+</trkpt>
+<trkpt lat="30.053017" lon="-91.594683">
+  <ele>0.000000</ele>
+<time>2002-05-25T18:24:37Z</time>
+</trkpt>
+<trkpt lat="30.054867" lon="-91.595200">
+  <ele>6.000000</ele>
+<time>2002-05-25T18:28:13Z</time>
+</trkpt>
+<trkpt lat="30.053733" lon="-91.594933">
+  <ele>2.000000</ele>
+<time>2002-05-25T18:31:36Z</time>
+</trkpt>
+<trkpt lat="30.053183" lon="-91.594783">
+  <ele>0.000000</ele>
+<time>2002-05-25T18:32:56Z</time>
+</trkpt>
+<trkpt lat="30.052633" lon="-91.594833">
+  <ele>0.000000</ele>
+<time>2002-05-25T18:34:02Z</time>
+</trkpt>
+<trkpt lat="30.052450" lon="-91.595433">
+  <ele>0.000000</ele>
+<time>2002-05-25T18:36:03Z</time>
+</trkpt>
+<trkpt lat="30.052483" lon="-91.595967">
+  <ele>0.000000</ele>
+<time>2002-05-25T18:36:48Z</time>
+</trkpt>
+<trkpt lat="30.052650" lon="-91.596783">
+  <ele>1.000000</ele>
+<time>2002-05-25T18:37:52Z</time>
+</trkpt>
+<trkpt lat="30.053133" lon="-91.597850">
+  <ele>0.000000</ele>
+<time>2002-05-25T18:39:18Z</time>
+</trkpt>
+<trkpt lat="30.053617" lon="-91.597967">
+  <ele>0.000000</ele>
+<time>2002-05-25T18:40:15Z</time>
+</trkpt>
+<trkpt lat="30.053967" lon="-91.597767">
+  <ele>6.000000</ele>
+<time>2002-05-25T18:41:25Z</time>
+</trkpt>
+<trkpt lat="30.053617" lon="-91.598083">
+  <ele>0.000000</ele>
+<time>2002-05-25T18:42:37Z</time>
+</trkpt>
+<trkpt lat="30.053200" lon="-91.597917">
+  <ele>0.000000</ele>
+<time>2002-05-25T18:44:01Z</time>
+</trkpt>
+<trkpt lat="30.052817" lon="-91.597517">
+  <ele>0.000000</ele>
+<time>2002-05-25T18:45:53Z</time>
+</trkpt>
+<trkpt lat="30.052567" lon="-91.596933">
+  <ele>0.000000</ele>
+<time>2002-05-25T18:46:54Z</time>
+</trkpt>
+<trkpt lat="30.052333" lon="-91.596433">
+  <ele>0.000000</ele>
+<time>2002-05-25T18:47:42Z</time>
+</trkpt>
+<trkpt lat="30.052250" lon="-91.595683">
+  <ele>0.000000</ele>
+<time>2002-05-25T18:48:41Z</time>
+</trkpt>
+<trkpt lat="30.052217" lon="-91.595017">
+  <ele>0.000000</ele>
+<time>2002-05-25T18:49:52Z</time>
+</trkpt>
+<trkpt lat="30.051883" lon="-91.594700">
+  <ele>0.000000</ele>
+<time>2002-05-25T18:50:49Z</time>
+</trkpt>
+<trkpt lat="30.051050" lon="-91.594400">
+  <ele>0.000000</ele>
+<time>2002-05-25T18:52:14Z</time>
+</trkpt>
+<trkpt lat="30.050567" lon="-91.594233">
+  <ele>0.000000</ele>
+<time>2002-05-25T18:52:56Z</time>
+</trkpt>
+<trkpt lat="30.050183" lon="-91.594100">
+  <ele>0.000000</ele>
+<time>2002-05-25T18:53:38Z</time>
+</trkpt>
+</trkseg>
+</trk>
+<trk>
+  <name>LOG-20020526</name>
+<trkseg>
+<trkpt lat="30.049100" lon="-91.593717">
+  <ele>0.000000</ele>
+<time>2002-05-26T18:55:11Z</time>
+</trkpt>
+<trkpt lat="30.048450" lon="-91.594250">
+  <ele>0.000000</ele>
+<time>2002-05-26T18:56:32Z</time>
+</trkpt>
+<trkpt lat="30.048083" lon="-91.594750">
+  <ele>0.000000</ele>
+<time>2002-05-26T18:57:24Z</time>
+</trkpt>
+<trkpt lat="30.047500" lon="-91.595450">
+  <ele>7.000000</ele>
+<time>2002-05-26T18:58:40Z</time>
+</trkpt>
+<trkpt lat="30.047067" lon="-91.596000">
+  <ele>0.000000</ele>
+<time>2002-05-26T18:59:28Z</time>
+</trkpt>
+</trkseg>
+</trk>
+<trk>
+  <name>LOG-20020527</name>
+<trkseg>
+<trkpt lat="30.046633" lon="-91.596600">
+  <ele>0.000000</ele>
+<time>2002-05-27T19:00:22Z</time>
+</trkpt>
+<trkpt lat="30.046400" lon="-91.597650">
+  <ele>0.000000</ele>
+<time>2002-05-27T19:01:41Z</time>
+</trkpt>
+<trkpt lat="30.046233" lon="-91.598467">
+  <ele>0.000000</ele>
+<time>2002-05-27T19:02:48Z</time>
+</trkpt>
+<trkpt lat="30.046317" lon="-91.598967">
+  <ele>0.000000</ele>
+<time>2002-05-27T19:03:43Z</time>
+</trkpt>
+<trkpt lat="30.046783" lon="-91.599283">
+  <ele>0.000000</ele>
+<time>2002-05-27T19:04:49Z</time>
+</trkpt>
+<trkpt lat="30.047133" lon="-91.599667">
+  <ele>0.000000</ele>
+<time>2002-05-27T19:05:57Z</time>
+</trkpt>
+</trkseg>
+</trk>
+</gpx>
diff --git a/gpsbabel/reference/track/trackfilter.gpx b/gpsbabel/reference/track/trackfilter.gpx
new file mode 100644 (file)
index 0000000..88190ad
--- /dev/null
@@ -0,0 +1,269 @@
+<?xml version="1.0"?>
+<gpx
+ version="1.0"
+creator="GPSBabel - http://gpsbabel.sourceforge.net"
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xmlns="http://www.topografix.com/GPX/1/0"
+xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/GPX/1/0/gpx.xsd">
+<time>2004-01-08T20:11:32Z</time>
+<trk>
+<trkseg>
+<trkpt lat="30.062183" lon="-91.610350">
+<ele>1.000000</ele>
+<time>2002-05-25T17:06:21Z</time>
+</trkpt>
+<trkpt lat="30.062783" lon="-91.610567">
+<ele>0.000000</ele>
+<time>2002-05-25T17:09:55Z</time>
+</trkpt>
+<trkpt lat="30.062700" lon="-91.608267">
+<ele>0.000000</ele>
+<time>2002-05-25T17:12:00Z</time>
+</trkpt>
+<trkpt lat="30.062333" lon="-91.607383">
+<ele>0.000000</ele>
+<time>2002-05-25T17:12:48Z</time>
+</trkpt>
+<trkpt lat="30.061533" lon="-91.605283">
+<ele>0.000000</ele>
+<time>2002-05-25T17:14:41Z</time>
+</trkpt>
+<trkpt lat="30.059783" lon="-91.599400">
+<ele>0.000000</ele>
+<time>2002-05-25T17:17:16Z</time>
+</trkpt>
+<trkpt lat="30.057800" lon="-91.596683">
+<ele>0.000000</ele>
+<time>2002-05-25T17:17:46Z</time>
+</trkpt>
+<trkpt lat="30.055383" lon="-91.594900">
+<ele>0.000000</ele>
+<time>2002-05-25T17:18:20Z</time>
+</trkpt>
+<trkpt lat="30.053883" lon="-91.592617">
+<ele>0.000000</ele>
+<time>2002-05-25T17:19:01Z</time>
+</trkpt>
+<trkpt lat="30.049733" lon="-91.589750">
+<ele>0.000000</ele>
+<time>2002-05-25T17:20:46Z</time>
+</trkpt>
+<trkpt lat="30.049017" lon="-91.589883">
+<ele>0.000000</ele>
+<time>2002-05-25T17:21:10Z</time>
+</trkpt>
+<trkpt lat="30.048800" lon="-91.592933">
+<ele>0.000000</ele>
+<time>2002-05-25T17:21:51Z</time>
+</trkpt>
+<trkpt lat="30.046233" lon="-91.596450">
+<ele>0.000000</ele>
+<time>2002-05-25T17:22:35Z</time>
+</trkpt>
+<trkpt lat="30.045517" lon="-91.598717">
+<ele>0.000000</ele>
+<time>2002-05-25T17:23:08Z</time>
+</trkpt>
+<trkpt lat="30.047300" lon="-91.600267">
+<ele>0.000000</ele>
+<time>2002-05-25T18:04:23Z</time>
+</trkpt>
+<trkpt lat="30.047000" lon="-91.599633">
+<ele>2.000000</ele>
+<time>2002-05-25T18:06:04Z</time>
+</trkpt>
+<trkpt lat="30.046433" lon="-91.599467">
+<ele>0.000000</ele>
+<time>2002-05-25T18:07:06Z</time>
+</trkpt>
+<trkpt lat="30.046200" lon="-91.598950">
+<ele>1.000000</ele>
+<time>2002-05-25T18:08:18Z</time>
+</trkpt>
+<trkpt lat="30.046367" lon="-91.597733">
+<ele>0.000000</ele>
+<time>2002-05-25T18:10:20Z</time>
+</trkpt>
+<trkpt lat="30.046350" lon="-91.597167">
+<ele>0.000000</ele>
+<time>2002-05-25T18:11:09Z</time>
+</trkpt>
+<trkpt lat="30.046783" lon="-91.596333">
+<ele>0.000000</ele>
+<time>2002-05-25T18:12:18Z</time>
+</trkpt>
+<trkpt lat="30.047450" lon="-91.595200">
+<ele>0.000000</ele>
+<time>2002-05-25T18:14:22Z</time>
+</trkpt>
+<trkpt lat="30.047800" lon="-91.594767">
+<ele>2.000000</ele>
+<time>2002-05-25T18:15:04Z</time>
+</trkpt>
+<trkpt lat="30.048250" lon="-91.594083">
+<ele>1.000000</ele>
+<time>2002-05-25T18:16:14Z</time>
+</trkpt>
+<trkpt lat="30.048683" lon="-91.593800">
+<ele>1.000000</ele>
+<time>2002-05-25T18:17:01Z</time>
+</trkpt>
+<trkpt lat="30.049350" lon="-91.593850">
+<ele>0.000000</ele>
+<time>2002-05-25T18:18:07Z</time>
+</trkpt>
+<trkpt lat="30.050317" lon="-91.593983">
+<ele>2.000000</ele>
+<time>2002-05-25T18:19:51Z</time>
+</trkpt>
+<trkpt lat="30.050783" lon="-91.594117">
+<ele>0.000000</ele>
+<time>2002-05-25T18:20:39Z</time>
+</trkpt>
+<trkpt lat="30.051233" lon="-91.594367">
+<ele>0.000000</ele>
+<time>2002-05-25T18:21:24Z</time>
+</trkpt>
+<trkpt lat="30.051800" lon="-91.594367">
+<ele>0.000000</ele>
+<time>2002-05-25T18:22:17Z</time>
+</trkpt>
+<trkpt lat="30.052217" lon="-91.594667">
+<ele>0.000000</ele>
+<time>2002-05-25T18:23:18Z</time>
+</trkpt>
+<trkpt lat="30.053017" lon="-91.594683">
+<ele>0.000000</ele>
+<time>2002-05-25T18:24:37Z</time>
+</trkpt>
+<trkpt lat="30.054867" lon="-91.595200">
+<ele>6.000000</ele>
+<time>2002-05-25T18:28:13Z</time>
+</trkpt>
+<trkpt lat="30.053733" lon="-91.594933">
+<ele>2.000000</ele>
+<time>2002-05-25T18:31:36Z</time>
+</trkpt>
+<trkpt lat="30.053183" lon="-91.594783">
+<ele>0.000000</ele>
+<time>2002-05-25T18:32:56Z</time>
+</trkpt>
+<trkpt lat="30.052633" lon="-91.594833">
+<ele>0.000000</ele>
+<time>2002-05-25T18:34:02Z</time>
+</trkpt>
+<trkpt lat="30.052450" lon="-91.595433">
+<ele>0.000000</ele>
+<time>2002-05-25T18:36:03Z</time>
+</trkpt>
+<trkpt lat="30.052483" lon="-91.595967">
+<ele>0.000000</ele>
+<time>2002-05-25T18:36:48Z</time>
+</trkpt>
+<trkpt lat="30.052650" lon="-91.596783">
+<ele>1.000000</ele>
+<time>2002-05-25T18:37:52Z</time>
+</trkpt>
+<trkpt lat="30.053133" lon="-91.597850">
+<ele>0.000000</ele>
+<time>2002-05-25T18:39:18Z</time>
+</trkpt>
+<trkpt lat="30.053617" lon="-91.597967">
+<ele>0.000000</ele>
+<time>2002-05-25T18:40:15Z</time>
+</trkpt>
+<trkpt lat="30.053967" lon="-91.597767">
+<ele>6.000000</ele>
+<time>2002-05-25T18:41:25Z</time>
+</trkpt>
+<trkpt lat="30.053617" lon="-91.598083">
+<ele>0.000000</ele>
+<time>2002-05-25T18:42:37Z</time>
+</trkpt>
+<trkpt lat="30.053200" lon="-91.597917">
+<ele>0.000000</ele>
+<time>2002-05-25T18:44:01Z</time>
+</trkpt>
+<trkpt lat="30.052817" lon="-91.597517">
+<ele>0.000000</ele>
+<time>2002-05-25T18:45:53Z</time>
+</trkpt>
+<trkpt lat="30.052567" lon="-91.596933">
+<ele>0.000000</ele>
+<time>2002-05-25T18:46:54Z</time>
+</trkpt>
+<trkpt lat="30.052333" lon="-91.596433">
+<ele>0.000000</ele>
+<time>2002-05-25T18:47:42Z</time>
+</trkpt>
+<trkpt lat="30.052250" lon="-91.595683">
+<ele>0.000000</ele>
+<time>2002-05-25T18:48:41Z</time>
+</trkpt>
+<trkpt lat="30.052217" lon="-91.595017">
+<ele>0.000000</ele>
+<time>2002-05-25T18:49:52Z</time>
+</trkpt>
+<trkpt lat="30.051883" lon="-91.594700">
+<ele>0.000000</ele>
+<time>2002-05-25T18:50:49Z</time>
+</trkpt>
+<trkpt lat="30.051050" lon="-91.594400">
+<ele>0.000000</ele>
+<time>2002-05-25T18:52:14Z</time>
+</trkpt>
+<trkpt lat="30.050567" lon="-91.594233">
+<ele>0.000000</ele>
+<time>2002-05-25T18:52:56Z</time>
+</trkpt>
+<trkpt lat="30.050183" lon="-91.594100">
+<ele>0.000000</ele>
+<time>2002-05-25T18:53:38Z</time>
+</trkpt>
+<trkpt lat="30.049100" lon="-91.593717">
+<ele>0.000000</ele>
+<time>2002-05-26T18:55:11Z</time>
+</trkpt>
+<trkpt lat="30.048450" lon="-91.594250">
+<ele>0.000000</ele>
+<time>2002-05-26T18:56:32Z</time>
+</trkpt>
+<trkpt lat="30.048083" lon="-91.594750">
+<ele>0.000000</ele>
+<time>2002-05-26T18:57:24Z</time>
+</trkpt>
+<trkpt lat="30.047500" lon="-91.595450">
+<ele>7.000000</ele>
+<time>2002-05-26T18:58:40Z</time>
+</trkpt>
+<trkpt lat="30.047067" lon="-91.596000">
+<ele>0.000000</ele>
+<time>2002-05-26T18:59:28Z</time>
+</trkpt>
+<trkpt lat="30.046633" lon="-91.596600">
+<ele>0.000000</ele>
+<time>2002-05-27T19:00:22Z</time>
+</trkpt>
+<trkpt lat="30.046400" lon="-91.597650">
+<ele>0.000000</ele>
+<time>2002-05-27T19:01:41Z</time>
+</trkpt>
+<trkpt lat="30.046233" lon="-91.598467">
+<ele>0.000000</ele>
+<time>2002-05-27T19:02:48Z</time>
+</trkpt>
+<trkpt lat="30.046317" lon="-91.598967">
+<ele>0.000000</ele>
+<time>2002-05-27T19:03:43Z</time>
+</trkpt>
+<trkpt lat="30.046783" lon="-91.599283">
+<ele>0.000000</ele>
+<time>2002-05-27T19:04:49Z</time>
+</trkpt>
+<trkpt lat="30.047133" lon="-91.599667">
+<ele>0.000000</ele>
+<time>2002-05-27T19:05:57Z</time>
+</trkpt>
+</trkseg>
+</trk>
+</gpx>
index bf4b2c8bef12f33324d89461a24c20e000a4d752..42937bd6d3a19915cbe05c35ed7d4e765e3d49e6 100755 (executable)
@@ -716,4 +716,15 @@ compare ${TMPDIR}/vitosmt.gpx reference/vitosmt.gpx
 ${PNAME} -t -i vitosmt,tzoffset=-7 -f reference/vitosmt.smt -o gpx -F ${TMPDIR}/vitosmt_t.gpx
 compare ${TMPDIR}/vitosmt_t.gpx reference/track/vitosmt_t.gpx
 
+#
+# tracks filter tests
+#
+
+rm -f ${TMPDIR}/trackfilter*
+
+${PNAME} -t -i gpx -f reference/track/trackfilter.gpx -x track,pack,split,title="LOG-%Y%m%d" -o gpx -F ${TMPDIR}/trackfilter-new.gpx
+grep -v "<time>" reference/track/trackfilter-new.gpx > ${TMPDIR}/trackfilter.ref
+grep -v "<time>" ${TMPDIR}/trackfilter-new.gpx > ${TMPDIR}/trackfilter.new
+compare ${TMPDIR}/trackfilter.ref ${TMPDIR}/trackfilter.new
+
 exit 0
diff --git a/gpsbabel/trackfilter.c b/gpsbabel/trackfilter.c
new file mode 100644 (file)
index 0000000..53723a8
--- /dev/null
@@ -0,0 +1,345 @@
+/*
+    Track manipulation filter
+
+    Copyright (C) 2005 Olaf Klein, o.b.klein@t-online.de
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
+
+ */
+#include <stdio.h>
+#include <time.h>
+#include "defs.h"
+
+#define MYNAME "tracks"
+
+#undef TRACKF_DBG
+
+static char *opt_pack = NULL;
+static char *opt_split = NULL;
+static char *opt_title = NULL;
+
+static
+arglist_t trackfilter_args[] = {
+       {"pack", &opt_pack, "Pack all tracks into one", NULL, ARGTYPE_BOOL},
+       {"split", &opt_split, "Split track by day", NULL, ARGTYPE_BOOL},
+       {"title", &opt_title, "Basic title for new track(s)", NULL, ARGTYPE_STRING},
+       {0, 0, 0, 0, 0}
+};
+
+typedef struct trkflt
+{
+       route_head *track;
+       time_t first_time;
+       time_t last_time;
+} trkflt_t;
+
+static trkflt_t *track_list = NULL;
+static int track_ct = 0;
+
+/*- dummy callbacks for track_disp_all ---------------------------------------------------*/
+
+static void 
+trackfilter_noop_w(const waypoint *w)
+{
+}
+
+static void 
+trackfilter_noop_t(const route_head *h)
+{
+}
+
+/*----------------------------------------------------------------------------------------*/
+
+static int
+trackfilter_qsort_cb(const void *a, const void *b)
+{
+       const trkflt_t *ra = a;
+       const trkflt_t *rb = b;
+
+       if (ra->first_time < rb->first_time) return -1;
+       else if (ra->first_time > rb->first_time) return +1;
+       else return 0;
+}
+
+/*----------------------------------------------------------------------------------------*/
+
+static void
+trackfilter_fill_track_list_cb(const route_head *trk)  /* callback for track_disp_all */
+{
+       int i;
+       waypoint *wpt, *prev;
+       queue *elem, *tmp;
+       
+       track_list[track_ct].track = (route_head *)trk;
+
+       i = 0;
+       prev = NULL;
+       
+       QUEUE_FOR_EACH((queue *)&trk->waypoint_list, elem, tmp)
+       {
+           wpt = (waypoint *)elem;
+           if (wpt->creation_time == 0) fatal(MYNAME ": Found track point without time!\n");
+           i++;
+           if (i == 1) track_list[track_ct].first_time = wpt->creation_time;
+           else if (i == trk->rte_waypt_ct) track_list[track_ct].last_time = wpt->creation_time;
+           if ((prev != NULL) && (prev->creation_time > wpt->creation_time))
+               fatal(MYNAME ": Track points bad ordered (timestamp)!\n");
+           prev = wpt;
+       }
+       track_ct++;
+}
+
+/*- global callbacks ---------------------------------------------------------------------*/
+
+static void
+trackfilter_init(const char *args) 
+{
+       int i, j;
+       int count = track_count();
+       trkflt_t prev;
+       
+#ifdef TRACKF_DBG
+       printf(MYNAME ": init...\n");
+#endif
+       if (count > 0)
+       {
+           track_list = (trkflt_t *) xcalloc(count, sizeof(*track_list));
+
+           /* check all tracks for time and order */
+       
+           track_ct = 0;
+           track_disp_all(trackfilter_fill_track_list_cb, trackfilter_noop_t, trackfilter_noop_w);
+           qsort(track_list, track_ct, sizeof(*track_list), trackfilter_qsort_cb);
+
+           for (i=1, j=0; i<track_ct; i++, j++)
+           {
+               prev = track_list[j];
+               if (prev.last_time >= track_list[i].first_time) fatal(MYNAME " Tracks overlaps in time!\n");
+           }
+       }
+}
+
+static void
+trackfilter_deinit(void) 
+{
+#ifdef TRACKF_DBG
+       printf(MYNAME ": deinit...\n");
+#endif
+       if (track_list != NULL)
+       {
+           xfree(track_list);
+           track_list = NULL;
+       }
+}
+
+#if 0
+static int 
+compare_wpt_time(const void *a, const void *b)
+{
+       const waypoint *pa = a;
+       const waypoint *pb = b;
+
+       if (pa->creation_time < pb->creation_time ) return -1;
+       else if (pa->creation_time > pb->creation_time ) return +1;
+       else return 0;
+}
+#endif
+
+static void
+trackfilter_init_rte_name(route_head *track, const time_t time)
+{
+       char buff[128], tbuff[128];
+       struct tm tm;
+       
+       tm = *localtime(&time);
+       
+       strftime(tbuff, sizeof(tbuff), "%Y%m%d", &tm);
+       
+       if (opt_title != NULL) 
+       {
+           if (strchr(opt_title, '%') != NULL)
+               strftime(buff, sizeof(buff), opt_title, &tm);
+           else
+               snprintf(buff, sizeof(buff), "%s-%s", opt_title, tbuff);
+       }
+       else
+       {
+           snprintf(buff, sizeof(buff), "%s-%s", track->rte_name, tbuff);
+       }
+       
+       if (track->rte_name != NULL) xfree(track->rte_name);
+       track->rte_name = xstrdup(buff);
+       
+}
+
+/*******************************************************************************************
+*
+* option "pack" (default)
+* 
+*******************************************************************************************/
+
+static void
+trackfilter_pack(void)
+{
+       int i, j, ct;
+       route_head *master, *curr;
+       queue *elem, *tmp;
+       waypoint *wpt;
+       waypoint **buff;
+       
+#ifdef TRACKF_DBG
+       printf(MYNAME ": packing tracks...\n");
+#endif
+       /* we fill up the first track by all others */
+       
+       master = track_list[0].track;
+       
+       if (opt_title != NULL)
+       {
+           if (master->rte_name != NULL)
+               xfree(master->rte_name);
+           master->rte_name = xstrdup(opt_title);
+       }
+       
+       for (i=1; i<track_ct; i++)
+       {
+           curr = track_list[i].track;
+           
+           ct = curr->rte_waypt_ct;
+           buff = (waypoint **)xcalloc(ct, sizeof(*buff));
+           
+           j = 0;
+           QUEUE_FOR_EACH((queue *)&curr->waypoint_list, elem, tmp)
+           {
+               wpt = (waypoint *)elem;
+               buff[j] = wpt;
+               j++;
+           }
+
+           for (j=0; j<ct; j++)
+           {
+               wpt = waypt_dupe(buff[j]);
+               route_del_wpt(curr, buff[j]);
+               route_add_wpt(master, wpt);
+           }
+           
+           xfree(buff);
+           
+           track_del_head(curr);
+       }
+}
+
+/*******************************************************************************************
+*
+* option "split"
+* 
+*******************************************************************************************/
+
+static void
+trackfilter_split(void)
+{
+       route_head *curr;
+       route_head *master = track_list[0].track;
+       int count = master->rte_waypt_ct;
+       
+       waypoint **buff;
+       waypoint *wpt;
+       queue *elem, *tmp;
+       int i, j;
+       struct tm t1, t2;
+       
+       if (count <= 1) return;
+       
+#ifdef TRACKF_DBG
+       printf(MYNAME ": splitting track...\n");
+#endif
+       
+       trackfilter_init_rte_name(master, track_list[0].first_time);
+       
+       buff = (waypoint **) xcalloc(count, sizeof(*buff));
+       
+       i = 0;
+       QUEUE_FOR_EACH((queue *)&master->waypoint_list, elem, tmp)
+       {
+           wpt = (waypoint *)elem;
+           buff[i++] = wpt;
+       }
+       
+       curr = NULL;
+       
+       for (i=0, j=1; j<count; i++, j++)
+       {
+           t1 = *localtime(&buff[i]->creation_time);
+           t2 = *localtime(&buff[j]->creation_time);
+           if ((t1.tm_year != t2.tm_year) || 
+               (t1.tm_mon != t2.tm_mon) || (t1.tm_mday != t2.tm_mday))
+           {
+#ifdef TRACKF_DBG
+               printf(MYNAME ": new day %02d.%02d.%04d\n", t2.tm_mday, t2.tm_mon+1, t2.tm_year+1900);
+#endif
+               curr = (route_head *) route_head_alloc();
+               trackfilter_init_rte_name(curr, buff[j]->creation_time);
+               
+               track_add_head(curr);
+           }
+           if (curr != NULL)
+           {
+               wpt = waypt_dupe(buff[j]);
+               route_del_wpt(master, buff[j]);
+               route_add_wpt(curr, wpt);
+           }
+       }
+       
+       xfree(buff);
+}
+
+/******************************************************************************************/
+
+static void 
+trackfilter_process(void)
+{
+       if (track_ct == 0) return;
+
+       if (opt_pack == NULL && opt_split == NULL)
+       {
+           trackfilter_pack();
+           return;
+       }
+
+       
+       if (opt_pack != 0 && track_ct > 0)
+       {
+           trackfilter_pack();
+           trackfilter_deinit();
+           trackfilter_init(NULL);
+       }
+       if (opt_split != 0 && track_ct > 0)
+       {
+           if (track_ct > 1) fatal(MYNAME ": Cannot split more than one track, please pack before!\n");
+           trackfilter_split();
+           trackfilter_deinit();
+           trackfilter_init(NULL);
+       }
+}
+
+/******************************************************************************************/
+
+filter_vecs_t trackfilter_vecs = {
+       trackfilter_init,
+       trackfilter_process,
+       trackfilter_deinit,
+       NULL,
+       trackfilter_args
+};